﻿using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis;
using System.Diagnostics;
using System.Linq;
using System;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Generic;
using System.Text;
namespace AugmentingGeneratorMethod
{
    class AugmentSyntaxReceiver : ISyntaxReceiver
    {
        // 获得类名
        public ClassDeclarationSyntax ClassToAugment { get; private set; }
        // 获得命名空间
        public NamespaceDeclarationSyntax SpaceToAugment { get; private set; }

        public StringBuilder strBuilder = new StringBuilder();

        public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
        {

            // 获取所有 using 指令
            IEnumerable<UsingDirectiveSyntax> usingDirectives = syntaxNode.DescendantNodes().OfType<UsingDirectiveSyntax>();
            if (usingDirectives.Any()) 
            {
                strBuilder.AppendLine("Using 指令:");
                foreach (var usingDirective in usingDirectives)
                {
                    if (!string.IsNullOrEmpty(usingDirective.Name.ToString()))
                    {
                        strBuilder.AppendLine($"using {usingDirective.Name}");
                    }

                }
            }
           
            //Debugger.Launch();
            if (syntaxNode is NamespaceDeclarationSyntax csd)
            {
                SpaceToAugment = csd;
            }
            // 判断是否有AugmentClass，如果有则赋值
            if (syntaxNode is ClassDeclarationSyntax classDeclaration && classDeclaration.Identifier.ValueText == "AugmentClass")
            {



                var properties = classDeclaration.Members.OfType<PropertyDeclarationSyntax>();
                strBuilder.AppendLine("类的属性:");
                foreach (var property in properties)
                {
                    strBuilder.AppendLine($"{property.Type} {property.Identifier.ValueText}");

                    // 获取属性的特性的信息
                    var propertyAttributes = property.AttributeLists
                        .SelectMany(attributeList =>
                            attributeList.Attributes.Select(attribute =>
                            {
                                var attributeName = attribute.Name is IdentifierNameSyntax identifierNameSyntax
                                    ? identifierNameSyntax.Identifier.Text
                                    : attribute.Name.ToString();

                                var descriptionValue = attribute.ArgumentList?.Arguments
                                    //.Where(arg => arg.NameEquals?.Name.Identifier.Text == "Description")
                                    .Select(arg => arg.Expression.ToString().Trim('\"'))
                                    .ToList();

                                return new { Name = attributeName, Description = descriptionValue.FirstOrDefault() };
                            })
                        );
                    foreach (var propertyAttribute in propertyAttributes)
                    {
                        strBuilder.AppendLine($"属性{property.Identifier.ValueText}声明特性为:[{propertyAttribute.Name}({propertyAttribute.Description})]");
                    }
                }

                // 获取类的方法
                var methods = classDeclaration.Members.OfType<MethodDeclarationSyntax>();
                strBuilder.AppendLine("类的方法:");
                foreach (var method in methods)
                {
                    strBuilder.AppendLine($"{method.ReturnType} {method.Identifier.ValueText}");
                }


                // 获取基类
                var baseType = classDeclaration.BaseList?.Types.FirstOrDefault()?.Type;
                strBuilder.AppendLine($"基类: {baseType}");
                // 获取实现的接口
                var interfaces = classDeclaration.BaseList?.Types
                    .Where(t => t.IsKind(SyntaxKind.SimpleBaseType))
                    .Select(t => ((SimpleBaseTypeSyntax)t).Type);
                //TODO:如何需要排除获取的接口，可能需要设置kind的类型
                // var interfaces = classDeclaration.BaseList?.Types
                //.Where(t => t.IsKind(SyntaxKind.SimpleBaseType) && 
                //            ((SimpleBaseTypeSyntax)t).Type.IsKind(SyntaxKind.InterfaceDeclaration))
                //.Select(t => ((SimpleBaseTypeSyntax)t).Type);


                strBuilder.AppendLine("实现的接口:");
                Console.WriteLine();
                foreach (var iface in interfaces)
                {
                    strBuilder.AppendLine($"{iface}");
                }

                // 获取类声明的特性
                var attributes = classDeclaration.AttributeLists.SelectMany(attributeList =>
                    attributeList.Attributes.Select(attribute =>
                        attribute.Name is IdentifierNameSyntax identifierNameSyntax
                            ? identifierNameSyntax.Identifier.Text
                            : attribute.Name.ToString()
                    )
                );
                strBuilder.AppendLine($"类声明的特性");
                foreach (var attribute in attributes)
                {
                    strBuilder.AppendLine($"{attribute}");
                }
                ClassToAugment = classDeclaration;
            }
        }
    }
}

